package com.aios.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.aios.dao.IrisDataMapper;
import com.aios.dao.IrisUserHasUserGroupMapper;
import com.aios.dao.IrisUserMapper;
import com.aios.entity.IrisData;
import com.aios.entity.IrisUser;
import com.aios.entity.IrisUserHasUserGroup;
import com.aios.entity.IrisUserHasUserGroupKey;
import com.aios.entity.mapper.AssignedState;
import com.aios.entity.mapper.IrisUserHasUserGroups;
import com.aios.entity.unit.StatusEnum;
import com.aios.service.ExistValidationEnum;
import com.aios.service.IrisUserService;
import com.aios.util.DataManipulator;
import com.aios.util.ListCompare;
import com.aios.util.Pager;
import com.aios.util.SessionKey;

@Service("irisUserService")
public class IrisUserServiceImpl extends AbstractListService implements
		IrisUserService {

	@Autowired
	private IrisUserMapper irisUserMapper;

	@Autowired
	private IrisUserHasUserGroupMapper irisUserHasUserGroupMapper;

	@Autowired
	private IrisDataMapper irisDataMapper;

	@Override
	public List<IrisUser> findAll() {
		return irisUserMapper.findAllByStatus(StatusEnum.ACTIVE
				.getStatusValue());
	}

	@Override
	public List<IrisUser> findAllNotDisabled() {
		return findAll();
	}

	@Override
	public List<IrisUser> findAllDisabled() {
		return irisUserMapper.findAllByStatus(StatusEnum.DELETED
				.getStatusValue());
	}

	@Override
	public IrisUser findById(Integer id) {
		return irisUserMapper.selectByPrimaryKey(id);
	}

	@Override
	public int save(IrisUser entity) {
		return this.irisUserMapper.insertWithoutID(entity);
	}

	@Override
	public int save(IrisUser entity, Integer systemUserID) {
		saveAddSettings(entity, systemUserID);
		return this.irisUserMapper.insertWithoutID(entity);
	}

	@Override
	public int update(IrisUser entity) {
		return this.irisUserMapper.updateByPrimaryKeySelective(entity);
	}

	@Override
	public int update(IrisUser entity, Integer systemUserID) {
		saveEditSettings(entity, systemUserID);
		return this.irisUserMapper.updateByPrimaryKeySelective(entity);
	}

	@Override
	public int delete(IrisUser entity) {
		return this.delete(entity.getId());
	}

	@Override
	public int delete(Integer id) {
		return this.irisUserMapper.deleteByPrimaryKey(id);
	}

	public ExistValidationEnum emailExistValidation(String email) {
		List<IrisUser> list = irisUserMapper.findByEmailAddress(email);

		if (list == null || list.size() == 0) {
			return ExistValidationEnum.NOT_EXIST;
		} else if (list.size() == 1) {
			return ExistValidationEnum.EXIST;
		} else {
			return ExistValidationEnum.MULTIPLE_EXIST;
		}
	}

	@Override
	public ExistValidationEnum emailExistValidation(String email, Integer id) {
		List<IrisUser> list = irisUserMapper.findEmailNotWithId(email, id);

		if (list == null || list.size() == 0) {
			return ExistValidationEnum.NOT_EXIST;
		} else if (list.size() == 1) {
			return ExistValidationEnum.EXIST;
		} else {
			return ExistValidationEnum.MULTIPLE_EXIST;
		}
	}

	@Override
	public List<AssignedState> findAssignedGroups(Integer id) {
		return this.irisUserMapper.findAssignedGroups(id);
	}

	@Override
	public List<IrisUserHasUserGroups> findAllWithGroups(int status) {
		return this.irisUserMapper.findAllWithGroups(status);
	}

	@Override
	public List<AssignedState> findAvailableGroups(Integer id) {
		return this.irisUserMapper.findAvailableGroups(id);
	}

	@Override
	public IrisUserHasUserGroups findByIdWithGroups(Integer id) {
		return this.irisUserMapper.findByIdWithGroups(id);
	}

	@Override
	public int updateGroupsList(IrisUser irisUser, List<Integer> selectedList,
			Integer systemUserID) {
		int returnValue = 0;

		if (selectedList == null) {
			selectedList = new ArrayList<Integer>();
		}

		List<Integer> existingList = this.irisUserMapper
				.findExistingGroupList(irisUser.getId());

		List<Integer> differenceList = ListCompare.getDifference(selectedList,
				existingList);

		if (!(differenceList.isEmpty())) {
			returnValue = this.removeUncheckedGroups(irisUser.getId(),
					differenceList);
		}

		differenceList = ListCompare.getDifference(existingList, selectedList);

		if (!(differenceList.isEmpty())) {
			returnValue = this.addNewGroups(irisUser.getId(), differenceList,
					systemUserID);
		}

		return returnValue;

	}

	private int addNewGroups(Integer userID, List<Integer> groupIDList,
			Integer systemUserID) {

		int returnValue = 0;
		for (int i = 0; i < groupIDList.size(); i++) {
			IrisUserHasUserGroup irisUserHasUserGroup = new IrisUserHasUserGroup();
			irisUserHasUserGroup.setIrisUserId(userID);
			irisUserHasUserGroup.setUserGroupId(groupIDList.get(i));

			saveAddSettings(irisUserHasUserGroup, systemUserID);
			returnValue = this.irisUserHasUserGroupMapper
					.insertSelective(irisUserHasUserGroup);
		}
		return returnValue;
	}

	private int removeUncheckedGroups(Integer userID, List<Integer> groupIDList) {

		int returnValue = 0;
		for (int i = 0; i < groupIDList.size(); i++) {
			IrisUserHasUserGroupKey key = new IrisUserHasUserGroupKey();
			key.setIrisUserId(userID);
			key.setUserGroupId(groupIDList.get(i));
			returnValue = this.irisUserHasUserGroupMapper
					.deleteByPrimaryKey(key);
		}
		return returnValue;
	}

	@Override
	public Pager viewPaginatedActiveList(Integer start, Integer size) {

		prepare(start, size);
		try {
			pager.setTotal(irisUserMapper.countAllByStatus(StatusEnum.ACTIVE
					.getStatusValue()));
			pager.setList(irisUserMapper.findListPaginated(
					StatusEnum.ACTIVE.getStatusValue(), start, size));
		} catch (Exception e) {
			// logger
			e.printStackTrace();
		}

		return pager;
	}

	@Override
	public Pager viewPaginatedActiveList(Integer start, Integer size,
			String sortColumn, String sortOrder) {
		// System.out.println("start:"+start+" size:"+" SortColumn:"+sortColumn+" SortOrder:"+sortOrder);
		prepare(start, size);
		try {
			pager.setTotal(irisUserMapper.countAllByStatus(StatusEnum.ACTIVE
					.getStatusValue()));
			pager.setList(irisUserMapper.findSortedListPaginated(
					StatusEnum.ACTIVE.getStatusValue(), start, size,
					sortColumn, sortOrder, ""));
		} catch (Exception e) {
			// logger
			e.printStackTrace();
		}

		return pager;
	}

	@Override
	public Pager viewPaginatedSearchList(Integer pageStart, Integer pageSize,
			DataManipulator manipulator) {
		try {

			if (manipulator.hasSearchParam()) {
				// System.out.println(manipulator.getSearchParamMap().get("NAME"));
				pager.setTotal(irisUserMapper.countAllByStatusSearched(
						StatusEnum.ACTIVE.getStatusValue(), manipulator
								.getSearchParamMap().get("NAME")));
				pager.setList(irisUserMapper.findSortedListPaginated(
						StatusEnum.ACTIVE.getStatusValue(), pageStart,
						pageSize, manipulator.getSortBy(), manipulator
								.getSortOrder(), manipulator
								.getSearchParamMap().get("NAME")));
			} else {
				pager.setTotal(irisUserMapper
						.countAllByStatus(StatusEnum.ACTIVE.getStatusValue()));
				pager.setList(irisUserMapper.findSortedListPaginated(
						StatusEnum.ACTIVE.getStatusValue(), pageStart,
						pageSize, manipulator.getSortBy(),
						manipulator.getSortOrder(), ""));
			}

		} catch (Exception e) {
			// logger
			e.printStackTrace();
		}

		return pager;
	}

	@Override
	public int saveGroupList(IrisUser irisUser, List<Integer> selectedList,
			Integer systemUserID) {

		if (selectedList != null) {
			this.addNewGroups(irisUser.getId(), selectedList, systemUserID);
		}

		return 0;
	}

	@Override
	public int findIdByEmailAddress(String email) {
		return irisUserMapper.findByEmailAddress(email).get(0).getId();
	}

	@Override
	public IrisUser findIrisUserByEmailAddress(String email) {

		List<IrisUser> list = irisUserMapper.findByEmailAddress(email);
		if (list != null && list.size() > 0) {
			return list.get(0);
		} else {
			// logger
			return null;
		}
	}

	@Override
	public int getCount() {
		return irisUserMapper.countAllByStatus(0);
	}

	@Override
	public IrisData findIrisData(Integer irisUserId) {
		return irisDataMapper.findByIrisUserId(irisUserId);
	}

	@Override
	public int saveIrisData(IrisUser irisUser, IrisData irisData,
			Integer systemUserId) {
		irisData.setIrisUserId(irisUser.getId());
		saveAddSettings(irisData, systemUserId);
		return irisDataMapper.insertWithoutId(irisData);
	}

	@Override
	public int updateIrisData(IrisUser irisUser, IrisData irisData,
			Integer systemUserId) {
		IrisData dataExist = irisDataMapper.findByIrisUserId(irisUser.getId());
		irisData.setIrisUserId(irisUser.getId());

		if (irisData.getLeftEye() == null || irisData.getLeftEye().equals("")) {
			irisData.setLeftEye("false");
		}
		if (irisData.getRightEye() == null || irisData.getRightEye().equals("")) {
			irisData.setRightEye("false");
		}
		if (irisData.getCard() == null || irisData.getCard().equals("")) {
			irisData.setCard("false");
		}
		if (irisData.getPin() == null || irisData.getPin().equals("")) {
			irisData.setPin("false");
		}

		if (dataExist != null) {
			irisData.setId(dataExist.getId());
			saveEditSettings(irisData, systemUserId);
			return irisDataMapper.updateByPrimaryKey(irisData);
		} else {
			saveAddSettings(irisData, systemUserId);
			return irisDataMapper.insertWithoutId(irisData);
		}
	}

	@Override
	public Pager viewPaginatedActiveList(Integer start, Integer size,
			DataManipulator manipulator) {
		prepare(start, size);
		try {
			/*
			 * pager.setTotal(irisUserMapper.countAllByStatus(StatusEnum.ACTIVE
			 * .getStatusValue()));
			 * pager.setList(irisUserMapper.findSortedListPaginated(
			 * StatusEnum.ACTIVE.getStatusValue(), start, size,
			 * manipulator.getSortBy(), manipulator.getSortOrder(),""));
			 */
			if (manipulator.hasSearchParam() && !manipulator.getSearchParamMap().get("NAME").equals("")) {
				// System.out.println(manipulator.getSearchParamMap().get("NAME"));
				pager.setTotal(irisUserMapper.countAllByStatusSearched(
						StatusEnum.ACTIVE.getStatusValue(), manipulator
								.getSearchParamMap().get("NAME")));
				pager.setList(irisUserMapper.findSortedListPaginated(
						StatusEnum.ACTIVE.getStatusValue(), start,
						size, manipulator.getSortBy(), manipulator
								.getSortOrder(), manipulator
								.getSearchParamMap().get("NAME")));
			} else {
				pager.setTotal(irisUserMapper
						.countAllByStatus(StatusEnum.ACTIVE.getStatusValue()));
				pager.setList(irisUserMapper.findSortedListPaginated(
						StatusEnum.ACTIVE.getStatusValue(), start,
						size, manipulator.getSortBy(),
						manipulator.getSortOrder(), ""));
			}
		} catch (Exception e) {
			// logger
			e.printStackTrace();
		}

		return pager;
	}

}
